package com.ssy.lingxi.platform.manage.serviceimpl.content;

import cn.hutool.core.collection.CollectionUtil;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.OrderSpecifier;
import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.core.types.dsl.NumberExpression;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import com.ssy.lingxi.common.constant.basic.EnableDisableStatus;
import com.ssy.lingxi.common.exception.BusinessException;
import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.model.vo.PageVO;
import com.ssy.lingxi.common.response.PageData;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.platform.manage.constant.ColumnTypeEnum;
import com.ssy.lingxi.platform.manage.constant.CommonBooleanEnum;
import com.ssy.lingxi.platform.manage.constant.RecommendLabelEnum;
import com.ssy.lingxi.platform.manage.constant.ShelfEnum;
import com.ssy.lingxi.platform.manage.entity.content.*;
import com.ssy.lingxi.platform.manage.model.request.common.CommonIdListRequest;
import com.ssy.lingxi.platform.manage.model.request.common.CommonIdPageRequest;
import com.ssy.lingxi.platform.manage.model.request.common.CommonIdRequest;
import com.ssy.lingxi.platform.manage.model.request.common.CommonStatusRequest;
import com.ssy.lingxi.platform.manage.model.request.content.*;
import com.ssy.lingxi.platform.manage.model.response.*;
import com.ssy.lingxi.platform.manage.repository.*;
import com.ssy.lingxi.platform.manage.service.content.IMemberInformationService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 内容能力-资讯管理
 * @author wyx
 * @version 2.0.0
 * @date 2021-09-28
 */
@Service
public class MemberInformationServiceImpl implements IMemberInformationService {

    @Resource
    private JPAQueryFactory jpaQueryFactory;
    @Resource
    private JdbcTemplate jdbcTemplate;
    @Resource
    private MemberInformationRepository memberInformationRepository;
    @Resource
    private MemberColumnRepository memberColumnRepository;
    @Resource
    private MemberLabelRepository memberLabelRepository;
    @Resource
    private MemberCategoryRepository memberCategoryRepository;
    @Resource
    private MemberInformationCollectRepository memberInformationCollectRepository;


    /**
     * 资讯列表
     * @param request 请求参数
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<MemberInformationPageResponse>> page(MemberInformationPageRequest request, UserLoginCacheDTO user) {
        StringBuilder sbList = new StringBuilder(" SELECT * FROM man_member_information ci WHERE 1 = 1 ");
        StringBuilder sbCount = new StringBuilder(" SELECT count(ci.id) FROM man_member_information ci WHERE 1 = 1 ");

        String where = "";
        where += " AND ci.member_id = " + user.getMemberId();
        where += " AND ci.member_role_id = " + user.getMemberRoleId();
        if (StringUtils.isNotBlank(request.getTitle())) {
            where += " AND ci.title LIKE '%" + request.getTitle() + "%' ";
        }
        if (request.getType() != null) {
            List<MemberColumn> columnList = memberColumnRepository.findAllByMemberIdAndMemberRoleIdAndStatusAndType(user.getMemberId(), user.getMemberRoleId(), CommonBooleanEnum.YES.getCode(), request.getType());
            if (CollectionUtil.isNotEmpty(columnList)) {
                List<Long> columnIdList = columnList.stream().map(MemberColumn::getId).collect(Collectors.toList());
                where += " AND ci.column_id IN(" + StringUtils.join(columnIdList, ",") + ")";
            }
        }
        if (request.getColumnId() != null) {
            where += " AND ci.column_id = " + request.getColumnId();
        }
        if (request.getThirdlyCategoryId() != null) {
            where += " AND ci.thirdly_category_id = " + request.getThirdlyCategoryId();
        }
        if (request.getRecommendLabel() != null) {
            where += " AND ci.recommend_label = " + request.getRecommendLabel();
        }
        if (request.getStatus() != null) {
            where += " AND ci.status = " + request.getStatus();
        }
        if (request.getLabelId() != null) {
            where += " AND ci.label_ids @> '" + request.getLabelId() + "'::jsonb ";
        }
        if (request.getStartTime() != null) {
            where += " AND ci.create_time >= " + request.getStartTime();
        }
        if (request.getEndTime() != null) {
            where += " AND ci.create_time <= " + request.getEndTime();
        }
        sbList.append(where);
        sbCount.append(where);

        sbList.append(" ORDER BY ci.create_time DESC ");
        sbList.append(" LIMIT ").append(request.getPageSize());
        sbList.append(" OFFSET ").append((request.getCurrent() - 1) * request.getPageSize());

        List<MemberInformationPageResponse> list = jdbcTemplate.query(sbList.toString(), new BeanPropertyRowMapper<>(MemberInformationPageResponse.class));
        Long totalCount = jdbcTemplate.queryForObject(sbCount.toString(), Long.class);

        //获取所有栏目、分类
        List<MemberColumn> allColumn = memberColumnRepository.findAllByMemberIdAndMemberRoleId(user.getMemberId(), user.getMemberRoleId());
        List<MemberCategory> allCategory = memberCategoryRepository.findAllByMemberIdAndMemberRoleId(user.getMemberId(), user.getMemberRoleId());

        //封装每个资讯对应的栏目、标签、分类
        list.forEach(a -> {
            //封装栏目名称、栏目分类
            MemberColumn memberColumn = allColumn.stream().filter(b -> b.getId().equals(a.getColumnId())).findFirst().orElse(new MemberColumn());
            a.setColumnName(memberColumn.getName());
            a.setType(memberColumn.getType());

            //封装推荐标签
            a.setLabelNames(a.getRecommendLabel() != null ? RecommendLabelEnum.getMessage(a.getRecommendLabel()) : null);

            //封装分类
            MemberCategory memberCategory = allCategory.stream().filter(c -> c.getId().equals(a.getThirdlyCategoryId())).findFirst().orElse(new MemberCategory());
            a.setCategoryName(memberCategory.getName());
        });

        return Wrapper.success(new PageData<>(totalCount, list));
    }

    /**
     * 资讯详情
     * @param request 请求参数
     * @return 查询结果
     */
    @Override
    public Wrapper<MemberInformation> get(CommonIdRequest request) {
        MemberInformation memberInformation = memberInformationRepository.findById(request.getId()).orElse(null);
        if (memberInformation == null) {
            throw new BusinessException(ResponseCode.MAN_RECORDS_DON_T_EXIST);
        }
        return Wrapper.success(memberInformation);
    }

    /**
     * 新增资讯
     * @param request 请求参数
     * @return 操作结果
     */
    @Override
    @Transactional
    public Wrapper<Void> add(MemberInformationRequest request, UserLoginCacheDTO user) {
        //校验推荐标签和排序
        if (request.getRecommendLabel() != null) {
            if (request.getSort() == null) {
                return Wrapper.fail(ResponseCode.PLATFORM_MANAGE_SORT_CANNOT_BE_EMPTY);
            }
            if (!request.getRecommendLabel().equals(RecommendLabelEnum.THIS_RECOMMENDED.getCode()) && memberInformationRepository.existsBySortAndRecommendLabel(request.getSort(), request.getRecommendLabel())) {
                return Wrapper.fail(ResponseCode.PLATFORM_MANAGE_THE_SAME_TAG_SORT_CANNOT_BE_REPEATED);
            }
        } else {
            if (request.getSort() != null) {
                return Wrapper.fail(ResponseCode.PLATFORM_MANAGE_RECOMMENDED_TAG_CANNOT_BE_EMPTY);
            }
        }

        //校验所选栏目是否被临时删除或下架
        MemberColumn memberColumn = memberColumnRepository.findById(request.getColumnId()).orElse(null);
        if (memberColumn == null) {
            return Wrapper.fail(ResponseCode.PLATFORM_MANAGE_COLUMN_DOES_NOT_EXIST);
        }
        if (memberColumn.getStatus().equals(EnableDisableStatus.DISABLE.getCode())) {
            return Wrapper.fail(ResponseCode.PLATFORM_MANAGE_COLUMN_STATUS_HAS_EXPIRED);
        }

        //校验所选的标签集合内是否有标签被临时删除或下架
        if (CollectionUtil.isNotEmpty(request.getLabelIds())) {
            List<MemberLabel> memberLabels = memberLabelRepository.findAllById(request.getLabelIds());
            if (memberLabels.size() != request.getLabelIds().size()) {
                return Wrapper.fail(ResponseCode.PLATFORM_MANAGE_MISMATCH);
            }
            MemberLabel label = memberLabels.stream().filter(a -> a.getStatus().equals(EnableDisableStatus.DISABLE.getCode())).findFirst().orElse(null);
            if (label != null) {
                return Wrapper.fail(ResponseCode.PLATFORM_MANAGE_LABEL_STATUS_HAS_EXPIRED);
            }
        }

        //校验推荐标签和栏目分类是否对应
        if (request.getRecommendLabel() != null && request.getRecommendLabel().equals(RecommendLabelEnum.MARKET_RECOMMENDED.getCode()) && !request.getType().equals(ColumnTypeEnum.MARKET.getCode())) {
            return Wrapper.fail(ResponseCode.PLATFORM_MANAGE_RECOMMENDED_TAGS_ARE_QUOTES_RECOMMENDATIONS);
        }
        if (request.getRecommendLabel() != null && request.getRecommendLabel().equals(RecommendLabelEnum.THIS_RECOMMENDED.getCode())) {
            if (!request.getType().equals(ColumnTypeEnum.INFORMATION.getCode())) {
                return Wrapper.fail(ResponseCode.PLATFORM_MANAGE_RECOMMENDED_TAGS_ARE_RECOMMENDED_FOR_THIS_COLUMN);
            }
            //每个栏目只能设置一个本栏推荐的资讯
            MemberInformation memberInformation = memberInformationRepository.findByColumnIdAndRecommendLabel(request.getColumnId(), request.getRecommendLabel());
            if (memberInformation != null) {
                memberInformation.setTitle(request.getTitle());
                memberInformation.setSort(request.getSort());
                memberInformation.setReadCount(request.getReadCount());
                memberInformation.setFirstCategoryId(request.getFirstCategoryId());
                memberInformation.setSecondCategoryId(request.getSecondCategoryId());
                memberInformation.setThirdlyCategoryId(request.getThirdlyCategoryId());
                memberInformation.setFirstCategoryName(request.getFirstCategoryName());
                memberInformation.setSecondCategoryName(request.getSecondCategoryName());
                memberInformation.setThirdlyCategoryName(request.getThirdlyCategoryName());
                memberInformation.setLabelIds(request.getLabelIds());
                memberInformation.setImageUrl(request.getImageUrl());
                memberInformation.setDigest(request.getDigest());
                memberInformation.setContent(request.getContent());
                memberInformationRepository.saveAndFlush(memberInformation);
                return Wrapper.success();
            }
        }

        //新增
        MemberInformation memberInformation = new MemberInformation();
        BeanUtils.copyProperties(request, memberInformation);
        memberInformation.setMemberId(user.getMemberId());
        memberInformation.setMemberRoleId(user.getMemberRoleId());
        memberInformationRepository.saveAndFlush(memberInformation);
        return Wrapper.success();
    }

    /**
     * 修改资讯
     * @param request 请求参数
     * @return 操作结果
     */
    @Override
    @Transactional
    public Wrapper<Void> update(MemberInformationRequest request, UserLoginCacheDTO user) {
        //校验推荐标签和排序
        if (request.getRecommendLabel() != null) {
            if (request.getSort() == null) {
                return Wrapper.fail(ResponseCode.PLATFORM_MANAGE_SORT_CANNOT_BE_EMPTY);
            }
            if (!request.getRecommendLabel().equals(RecommendLabelEnum.THIS_RECOMMENDED.getCode())) {
                MemberInformation existsMemberInformation = memberInformationRepository.findByMemberIdAndMemberRoleIdAndSortAndRecommendLabel(user.getMemberId(), user.getMemberRoleId(), request.getSort(), request.getRecommendLabel());
                if (existsMemberInformation != null && existsMemberInformation.getId() - request.getId() != 0) {
                    return Wrapper.fail(ResponseCode.PLATFORM_MANAGE_THE_SAME_TAG_SORT_CANNOT_BE_REPEATED);
                }
            }
        } else {
            if (request.getSort() != null) {
                return Wrapper.fail(ResponseCode.PLATFORM_MANAGE_RECOMMENDED_TAG_CANNOT_BE_EMPTY);
            }
        }

        //校验所选栏目是否被临时删除或下架
        MemberColumn memberColumn = memberColumnRepository.findById(request.getColumnId()).orElse(null);
        if (memberColumn == null) {
            return Wrapper.fail(ResponseCode.PLATFORM_MANAGE_COLUMN_DOES_NOT_EXIST);
        }
        if (memberColumn.getStatus().equals(EnableDisableStatus.DISABLE.getCode())) {
            return Wrapper.fail(ResponseCode.PLATFORM_MANAGE_COLUMN_STATUS_HAS_EXPIRED);
        }

        //校验所选的标签集合内是否有标签被临时删除或下架
        if (CollectionUtil.isNotEmpty(request.getLabelIds())) {
            List<MemberLabel> memberLabels = memberLabelRepository.findAllById(request.getLabelIds());
            if (memberLabels.size() != request.getLabelIds().size()) {
                return Wrapper.fail(ResponseCode.PLATFORM_MANAGE_MISMATCH);
            }
            MemberLabel label = memberLabels.stream().filter(a -> a.getStatus().equals(EnableDisableStatus.DISABLE.getCode())).findFirst().orElse(null);
            if (label != null) {
                return Wrapper.fail(ResponseCode.PLATFORM_MANAGE_LABEL_STATUS_HAS_EXPIRED);
            }
        }

        //校验推荐标签和栏目分类是否对应
        if (request.getRecommendLabel() != null && request.getRecommendLabel().equals(RecommendLabelEnum.MARKET_RECOMMENDED.getCode()) && !request.getType().equals(ColumnTypeEnum.MARKET.getCode())) {
            return Wrapper.fail(ResponseCode.PLATFORM_MANAGE_RECOMMENDED_TAGS_ARE_QUOTES_RECOMMENDATIONS);
        }
        if (request.getRecommendLabel() != null && request.getRecommendLabel().equals(RecommendLabelEnum.THIS_RECOMMENDED.getCode())) {
            if (!request.getType().equals(ColumnTypeEnum.INFORMATION.getCode())) {
                return Wrapper.fail(ResponseCode.PLATFORM_MANAGE_RECOMMENDED_TAGS_ARE_RECOMMENDED_FOR_THIS_COLUMN);
            }
            //每个栏目只能设置一个本栏推荐的资讯，所以将旧的本栏推荐资讯删除，避免造成同个栏目有两条本栏推荐资讯
            MemberInformation memberInformation = memberInformationRepository.findByColumnIdAndRecommendLabel(request.getColumnId(), request.getRecommendLabel());
            if (memberInformation != null && memberInformation.getId() - request.getId() != 0) {
                memberInformationRepository.deleteById(memberInformation.getId());
            }
        }

        //修改
        MemberInformation memberInformation = memberInformationRepository.findById(request.getId()).orElse(null);
        if (memberInformation == null) {
            throw new BusinessException(ResponseCode.MAN_RECORDS_DON_T_EXIST);
        }
        if (memberInformation.getStatus().equals(ShelfEnum.ON_SHELF.getCode())) {
            throw new BusinessException(ResponseCode.MAN_DATA_STATUS_INCORRECT_OPERATE_INVALID);
        }
        BeanUtils.copyProperties(request, memberInformation);
        memberInformationRepository.saveAndFlush(memberInformation);
        return Wrapper.success();
    }

    /**
     * 上架/下架
     * @param request 请求参数
     * @return 操作结果
     */
    @Override
    public Wrapper<Void> updateStatus(CommonStatusRequest request, UserLoginCacheDTO user) {
        MemberInformation memberInformation = memberInformationRepository.findById(request.getId()).orElse(null);
        if (memberInformation == null) {
            throw new BusinessException(ResponseCode.MAN_RECORDS_DON_T_EXIST);
        }
        memberInformation.setStatus(request.getShelfStatus());
        memberInformationRepository.saveAndFlush(memberInformation);
        return Wrapper.success();
    }

    /**
     * 删除资讯
     * @param request 请求参数
     * @return 操作结果
     */
    @Override
    @Transactional
    public Wrapper<Void> delete(CommonIdRequest request, UserLoginCacheDTO user) {
        MemberInformation memberInformation = memberInformationRepository.findById(request.getId()).orElse(null);
        if (memberInformation == null) {
            throw new BusinessException(ResponseCode.MAN_RECORDS_DON_T_EXIST);
        }
        if (memberInformation.getStatus().equals(ShelfEnum.ON_SHELF.getCode())) {
            throw new BusinessException(ResponseCode.MAN_DATA_STATUS_INCORRECT_OPERATE_INVALID);
        }
        memberInformationRepository.delete(memberInformation);
        return Wrapper.success();
    }

    /**
     * 批量删除/上架/下架
     * @param request 请求参数
     * @return 操作结果
     */
    @Override
    @Transactional
    public Wrapper<Void> batch(MemberInformationBatchRequest request, UserLoginCacheDTO user) {
        //根据资讯ID获取资讯集合
        List<MemberInformation> list = memberInformationRepository.findAllById(request.getIds());

        //批量删除
        if (request.getType() == 1) {
            if (list.stream().anyMatch(a -> a.getStatus().equals(ShelfEnum.ON_SHELF.getCode()))) {
                throw new BusinessException(ResponseCode.MAN_DATA_STATUS_INCORRECT_OPERATE_INVALID);
            }
            memberInformationRepository.deleteAll(list);
        }
        //批量上架
        if (request.getType() == 2) {
            if (list.stream().anyMatch(a -> a.getStatus().equals(ShelfEnum.ON_SHELF.getCode()))) {
                throw new BusinessException(ResponseCode.MAN_DATA_STATUS_INCORRECT_OPERATE_INVALID);
            }
            list = list.stream().peek(a -> a.setStatus(ShelfEnum.ON_SHELF.getCode())).collect(Collectors.toList());
            memberInformationRepository.saveAll(list);
        }
        //批量下架
        if (request.getType() == 3) {
            if (list.stream().anyMatch(a -> !a.getStatus().equals(ShelfEnum.ON_SHELF.getCode()))) {
                throw new BusinessException(ResponseCode.MAN_DATA_STATUS_INCORRECT_OPERATE_INVALID);
            }
            list = list.stream().peek(a -> a.setStatus(ShelfEnum.OFF_SHELF.getCode())).collect(Collectors.toList());
            memberInformationRepository.saveAll(list);
        }

        return Wrapper.success();
    }

    /**
     * 根据推荐标签获取
     * @param request 请求参数
     * @return 查询结果
     */
    @Override
    public Wrapper<List<MemberInformationResponse>> findAllByRecommendLabel(RecommendLabelRequest request, UserLoginCacheDTO user) {
        List<MemberInformation> list = memberInformationRepository.findAllByMemberIdAndMemberRoleIdAndRecommendLabelAndStatus(user.getMemberId(), user.getMemberRoleId(), request.getRecommendLabel(), ShelfEnum.ON_SHELF.getCode(), Sort.by("sort"));
        List<MemberColumn> columnList = memberColumnRepository.findAllByMemberIdAndMemberRoleId(user.getMemberId(), user.getMemberRoleId());
        return Wrapper.success(
                list.stream().map(a -> {
                    MemberInformationResponse response = new MemberInformationResponse();
                    BeanUtils.copyProperties(a, response);
                    MemberColumn memberColumn = columnList.stream().filter(b -> b.getId().equals(a.getColumnId())).findFirst().orElse(new MemberColumn());
                    response.setColumnName(memberColumn.getName());
                    return response;
                }).collect(Collectors.toList())
        );
    }

    /**
     * 最新发布
     * @return 查询结果
     */
    @Override
    public Wrapper<List<MemberInformationResponse>> latest(UserLoginCacheDTO user) {
        Pageable pageable = PageRequest.of(0, 8, Sort.by("createTime").descending());
        Page<MemberInformation> page = memberInformationRepository.findAllByMemberIdAndMemberRoleIdAndStatus(user.getMemberId(), user.getMemberRoleId(), ShelfEnum.ON_SHELF.getCode(), pageable);

        List<MemberInformation> list = page.getContent();
        List<MemberColumn> columnList = memberColumnRepository.findAllByMemberIdAndMemberRoleId(user.getMemberId(), user.getMemberRoleId());
        return Wrapper.success(
                list.stream().map(a -> {
                    MemberInformationResponse response = new MemberInformationResponse();
                    BeanUtils.copyProperties(a, response);
                    MemberColumn memberColumn = columnList.stream().filter(b -> b.getId().equals(a.getColumnId())).findFirst().orElse(new MemberColumn());
                    response.setColumnName(memberColumn.getName());
                    return response;
                }).collect(Collectors.toList())
        );
    }

    /**
     * 最多阅读
     * @return 查询结果
     */
    @Override
    public Wrapper<List<MemberInformationResponse>> maximumRead(UserLoginCacheDTO user) {
        Pageable pageable = PageRequest.of(0, 8, Sort.by("readCount").descending());
        Page<MemberInformation> page = memberInformationRepository.findAllByMemberIdAndMemberRoleIdAndStatus(user.getMemberId(), user.getMemberRoleId(), ShelfEnum.ON_SHELF.getCode(), pageable);

        List<MemberInformation> list = page.getContent();
        List<MemberColumn> columnList = memberColumnRepository.findAllByMemberIdAndMemberRoleId(user.getMemberId(), user.getMemberRoleId());
        return Wrapper.success(
                list.stream().map(a -> {
                    MemberInformationResponse response = new MemberInformationResponse();
                    BeanUtils.copyProperties(a, response);
                    MemberColumn memberColumn = columnList.stream().filter(b -> b.getId().equals(a.getColumnId())).findFirst().orElse(new MemberColumn());
                    response.setColumnName(memberColumn.getName());
                    return response;
                }).collect(Collectors.toList())
        );
    }

    /**
     * 最多收藏
     * @return 查询结果
     */
    @Override
    public Wrapper<List<MemberInformationResponse>> maximumCollect(UserLoginCacheDTO user) {
        Pageable pageable = PageRequest.of(0, 8, Sort.by("collectCount").descending());
        Page<MemberInformation> page = memberInformationRepository.findAllByMemberIdAndMemberRoleIdAndStatus(user.getMemberId(), user.getMemberRoleId(), ShelfEnum.ON_SHELF.getCode(), pageable);

        List<MemberInformation> list = page.getContent();
        List<MemberColumn> columnList = memberColumnRepository.findAllByMemberIdAndMemberRoleId(user.getMemberId(), user.getMemberRoleId());
        return Wrapper.success(
                list.stream().map(a -> {
                    MemberInformationResponse response = new MemberInformationResponse();
                    BeanUtils.copyProperties(a, response);
                    MemberColumn contentColumn = columnList.stream().filter(b -> b.getId().equals(a.getColumnId())).findFirst().orElse(new MemberColumn());
                    response.setColumnName(contentColumn.getName());
                    return response;
                }).collect(Collectors.toList())
        );
    }

    /**
     * 根据分类获取
     * @param request 请求参数
     * @return 查询结果
     */
    @Override
    public Wrapper<List<MemberInformationColumnResponse>> findAllByCategory(CommonIdRequest request, UserLoginCacheDTO user) {
        //获取所有栏目
        List<MemberColumn> columnList = memberColumnRepository.findAllByMemberIdAndMemberRoleIdAndStatus(user.getMemberId(), user.getMemberRoleId(), CommonBooleanEnum.YES.getCode(), Sort.by("sort"));
        if (CollectionUtil.isEmpty(columnList)) {
            return Wrapper.success(new ArrayList<>());
        }

        //根据栏目ID集合、分类ID获取资讯
        List<MemberInformation> list = memberInformationRepository.findAllByColumnIdInAndStatusAndThirdlyCategoryId(
                columnList.stream().map(MemberColumn::getId).collect(Collectors.toList()),
                ShelfEnum.ON_SHELF.getCode(),
                request.getId()
        );

        //筛选出有资讯数据的栏目
        columnList = columnList.stream().filter(a ->
                list.stream().anyMatch(b -> b.getColumnId().equals(a.getId()))
        ).collect(Collectors.toList());
        if (CollectionUtil.isEmpty(columnList)) {
            return Wrapper.success(new ArrayList<>());
        }

        //根据栏目ID分组获取每一组栏目下的资讯
        Map<Long, List<MemberInformation>> map = list.stream().collect(Collectors.groupingBy(MemberInformation::getColumnId));

        //封装每一组栏目下的资讯（资讯按发布时间倒序，每一组栏目展示8条资讯）
        List<MemberInformationColumnResponse> responseList = columnList.stream().map(a -> {
            MemberInformationColumnResponse response = new MemberInformationColumnResponse();
            response.setColumnId(a.getId());
            response.setColumnName(a.getName());

            List<MemberInformation> informationList = map.get(a.getId());
            if (CollectionUtil.isNotEmpty(informationList)) {

                informationList = informationList.stream().sorted(Comparator.comparingLong(
                        MemberInformation::getCreateTime
                ).reversed()).collect(Collectors.toList());

                response.setList(informationList.stream().limit(8).collect(Collectors.toList()));
            }

            return response;
        }).collect(Collectors.toList());

        return Wrapper.success(responseList);
    }

    /**
     * 根据栏目获取
     * @param request 请求参数
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<MemberInformationResponse>> pageByColumnLabel(CommonIdPageRequest request, UserLoginCacheDTO user) {
        Pageable pageable = PageRequest.of(request.getCurrent() - 1, request.getPageSize(), Sort.by("createTime").descending());
        Page<MemberInformation> page = memberInformationRepository.findAllByStatusAndColumnId(ShelfEnum.ON_SHELF.getCode(), request.getId(), pageable);

        List<MemberColumn> columnList = memberColumnRepository.findAllByMemberIdAndMemberRoleId(user.getMemberId(), user.getMemberRoleId());
        List<MemberInformationResponse> list = page.getContent().stream().map(a -> {
            MemberInformationResponse response = new MemberInformationResponse();
            BeanUtils.copyProperties(a, response);
            MemberColumn memberColumn = columnList.stream().filter(b -> b.getId().equals(a.getColumnId())).findFirst().orElse(new MemberColumn());
            response.setColumnName(memberColumn.getName());
            return response;
        }).collect(Collectors.toList());

        return Wrapper.success(new PageData<>(page.getTotalElements(), list));
    }

    /**
     * 资讯栏目
     * @return 查询结果
     */
    @Override
    public Wrapper<List<MemberInformationColumnResponse>> informationColumn(UserLoginCacheDTO user) {
        //获取所有栏目分类为'资讯'的栏目
        List<MemberColumn> columnList = memberColumnRepository.findAllByMemberIdAndMemberRoleIdAndStatusAndType(user.getMemberId(), user.getMemberRoleId(), CommonBooleanEnum.YES.getCode(), ColumnTypeEnum.INFORMATION.getCode(), Sort.by("sort"));
        if (CollectionUtil.isEmpty(columnList)) {
            return Wrapper.success(new ArrayList<>());
        }

        //根据栏目ID集合获取资讯
        List<MemberInformation> list = memberInformationRepository.findAllByColumnIdInAndStatus(
                columnList.stream().map(MemberColumn::getId).collect(Collectors.toList()),
                ShelfEnum.ON_SHELF.getCode()
        );

        //筛选出有资讯数据的栏目
        columnList = columnList.stream().filter(a ->
                list.stream().anyMatch(b -> b.getColumnId().equals(a.getId()))
        ).collect(Collectors.toList());
        if (CollectionUtil.isEmpty(columnList)) {
            return Wrapper.success(new ArrayList<>());
        }

        //根据栏目ID分组获取每一组栏目下的资讯
        Map<Long, List<MemberInformation>> map = list.stream().collect(Collectors.groupingBy(MemberInformation::getColumnId));

        //如果栏目下有'本栏推荐'的资讯需要移动下标到第一
        List<MemberInformationColumnResponse> responseList = columnList.stream().map(a -> {
            MemberInformationColumnResponse response = new MemberInformationColumnResponse();
            response.setColumnId(a.getId());
            response.setColumnName(a.getName());

            List<MemberInformation> informationList = map.get(a.getId());
            if (CollectionUtil.isNotEmpty(informationList)) {
                MemberInformation memberInformation = null;
                for (int i = 0; i < informationList.size(); i++) {
                    MemberInformation information = informationList.get(i);
                    if (information.getRecommendLabel() != null && information.getRecommendLabel().equals(RecommendLabelEnum.THIS_RECOMMENDED.getCode())) {
                        memberInformation = informationList.remove(i);
                        break;
                    }
                }

                informationList = informationList.stream().sorted(Comparator.comparingLong(
                        MemberInformation::getCreateTime
                ).reversed()).collect(Collectors.toList());

                if (memberInformation != null) {
                    informationList.add(0, memberInformation);
                }

                response.setList(informationList.stream().limit(8).collect(Collectors.toList()));
            }

            return response;
        }).collect(Collectors.toList());

        return Wrapper.success(responseList);
    }

    /**
     * 搜索
     * @param request 请求参数
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<MemberInformationResponse>> search(ContentInformationSearchRequest request, UserLoginCacheDTO user) {
        //表实体
        QMemberInformation qMemberInformation = QMemberInformation.memberInformation;

        //构造查询条件
        BooleanBuilder predicates = new BooleanBuilder();
        predicates.and(qMemberInformation.status.eq(ShelfEnum.ON_SHELF.getCode()));
        predicates.and(qMemberInformation.memberId.eq(user.getMemberId()));
        predicates.and(qMemberInformation.memberRoleId.eq(user.getMemberRoleId()));

        if (StringUtils.isNotBlank(request.getKeyword())) {
            //标题
            predicates.and(qMemberInformation.title.contains(request.getKeyword()));

            //栏目
            List<MemberColumn> columnList = memberColumnRepository.findAllByMemberIdAndMemberRoleIdAndNameContainingAndStatus(user.getMemberId(), user.getMemberRoleId(), request.getKeyword(), CommonBooleanEnum.YES.getCode());
            if (CollectionUtil.isNotEmpty(columnList)) {
                List<Long> columnIdList = columnList.stream().map(MemberColumn::getId).collect(Collectors.toList());
                predicates.and(qMemberInformation.columnId.in(columnIdList));
            }

            //一级分类、二级分类、三级分类
            List<MemberCategory> categoryList = memberCategoryRepository.findAllByMemberIdAndMemberRoleIdAndNameContaining(user.getMemberId(), user.getMemberRoleId(), request.getKeyword());
            if (CollectionUtil.isNotEmpty(categoryList)) {
                List<Long> firstCategoryIdList = categoryList.stream().filter(a -> a.getLevel().equals(1)).map(MemberCategory::getId).collect(Collectors.toList());
                if (CollectionUtil.isNotEmpty(firstCategoryIdList)) {
                    predicates.and(qMemberInformation.firstCategoryId.in(firstCategoryIdList));
                }
                List<Long> secondCategoryIdList = categoryList.stream().filter(a -> a.getLevel().equals(2)).map(MemberCategory::getId).collect(Collectors.toList());
                if (CollectionUtil.isNotEmpty(secondCategoryIdList)) {
                    predicates.and(qMemberInformation.secondCategoryId.in(secondCategoryIdList));
                }
                List<Long> thirdlyCategoryIdList = categoryList.stream().filter(a -> a.getLevel().equals(3)).map(MemberCategory::getId).collect(Collectors.toList());
                if (CollectionUtil.isNotEmpty(thirdlyCategoryIdList)) {
                    predicates.and(qMemberInformation.thirdlyCategoryId.in(thirdlyCategoryIdList));
                }
            }

            //摘要
            predicates.and(qMemberInformation.digest.contains(request.getKeyword()));

            //文章内容
            predicates.and(qMemberInformation.content.contains(request.getKeyword()));
        }

        JPAQuery<MemberInformationResponse> query = jpaQueryFactory
                .select(Projections.constructor(MemberInformationResponse.class,
                        qMemberInformation.id,
                        qMemberInformation.columnId,
                        qMemberInformation.title,
                        qMemberInformation.recommendLabel,
                        qMemberInformation.sort,
                        qMemberInformation.labelIds,
                        qMemberInformation.imageUrl,
                        qMemberInformation.digest,
                        qMemberInformation.content,
                        qMemberInformation.status,
                        qMemberInformation.createTime,
                        qMemberInformation.collectCount))
                .from(qMemberInformation);

        long totalCount = query.where(predicates).fetchCount();

        List<MemberInformationResponse> list = query.orderBy(qMemberInformation.id.desc()).offset(request.getCurrentOffset()).limit(request.getPageSize()).fetch();

        //获取所有栏目
        List<MemberColumn> allColumn = memberColumnRepository.findAllByMemberIdAndMemberRoleId(user.getMemberId(), user.getMemberRoleId());

        //封装栏目名称
        list.forEach(a -> {
            MemberColumn memberColumn = allColumn.stream().filter(b -> b.getId().equals(a.getColumnId())).findFirst().orElse(new MemberColumn());
            a.setColumnName(memberColumn.getName());
        });

        return Wrapper.success(new PageData<>(totalCount, list));
    }

    /**
     * 根据ID获取
     * @param request 请求参数
     * @return 查询结果
     */
    @Override
    public Wrapper<MemberInformationResponse> findById(CommonIdRequest request, UserLoginCacheDTO user) {
        //根据id获取资讯
        MemberInformation information = memberInformationRepository.findById(request.getId()).orElse(null);
        if (information == null) {
            throw new BusinessException(ResponseCode.MAN_RECORDS_DON_T_EXIST);
        }
        if (information.getStatus().equals(ShelfEnum.OFF_SHELF.getCode())) {
            throw new BusinessException(ResponseCode.MAN_DISABLE);
        }

        //拷贝
        MemberInformationResponse response = new MemberInformationResponse();
        BeanUtils.copyProperties(information, response);

        //栏目名称
        MemberColumn memberColumn = memberColumnRepository.findById(response.getColumnId()).orElse(new MemberColumn());
        response.setColumnName(memberColumn.getName());

        //上一篇/下一篇
        List<MemberInformation> list = memberInformationRepository.findAllByColumnIdAndStatus(information.getColumnId(), ShelfEnum.ON_SHELF.getCode(), Sort.by("createTime").descending());
        for (int i = 0; i < list.size(); i++) {
            MemberInformation memberInformation = list.get(i);
            if (memberInformation.getId().equals(response.getId())) {
                if (i != 0) {
                    MemberInformation lastContentLabel = list.get(i - 1);
                    response.setLastContentLabel(lastContentLabel);
                }
                if (list.size() - 1 != i) {
                    MemberInformation nextContentLabel = list.get(i + 1);
                    response.setNextContentLabel(nextContentLabel);
                }
                break;
            }
        }

        //收藏状态
        if (user != null) {
            Boolean collectStatus = memberInformationCollectRepository.existsByInformationIdAndMemberIdAndUserId(information.getId(), user.getMemberId(), user.getUserId());
            response.setCollectStatus(collectStatus);
        }

        //查看详情增加浏览量
        information.setReadCount(information.getReadCount() + 1);
        memberInformationRepository.saveAndFlush(information);

        return Wrapper.success(response);
    }

    /**
     * 根据ID集合获取
     * @param request 请求参数
     * @return 查询结果
     */
    @Override
    public Wrapper<List<MemberInformationListResponse>> findByIdIn(CommonIdListRequest request, UserLoginCacheDTO user) {
        //根据资讯ID集合获取资讯
        List<MemberInformation> list = memberInformationRepository.findAllById(request.getIdList());
        if (CollectionUtil.isEmpty(list)) {
            return Wrapper.success(new ArrayList<>());
        }

        //获取所有栏目
        List<MemberColumn> allColumn = memberColumnRepository.findAllByMemberIdAndMemberRoleId(user.getMemberId(), user.getMemberRoleId());

        //封装
        return Wrapper.success(list.stream()
                .sorted(Comparator.comparingInt(a -> request.getIdList().indexOf(a.getId())))
                .map(a -> {
                    MemberInformationListResponse response = new MemberInformationListResponse();
                    BeanUtils.copyProperties(a, response);
                    MemberColumn memberColumn = allColumn.stream().filter(b -> b.getId().equals(a.getColumnId())).findFirst().orElse(new MemberColumn());
                    response.setColumnName(memberColumn.getName());
                    return response;
                }).collect(Collectors.toList()));
    }

    /**
     * 同类资讯
     * @param request 请求参数
     * @return 查询结果
     */
    @Override
    public Wrapper<List<MemberInformationResponse>> related(CommonIdRequest request, UserLoginCacheDTO user) {
        //根据id获取资讯
        MemberInformation information = memberInformationRepository.findById(request.getId()).orElse(null);
        if (information == null) {
            return Wrapper.fail(ResponseCode.MAN_RECORDS_DON_T_EXIST);
        }

        //表实体
        QMemberInformation qMemberInformation = QMemberInformation.memberInformation;

        //根据相同栏目与分类获取相关资讯
        JPAQuery<MemberInformationResponse> query = jpaQueryFactory
                .select(Projections.constructor(MemberInformationResponse.class,
                        qMemberInformation.id,
                        qMemberInformation.columnId,
                        qMemberInformation.title,
                        qMemberInformation.recommendLabel,
                        qMemberInformation.sort,
                        qMemberInformation.labelIds,
                        qMemberInformation.imageUrl,
                        qMemberInformation.digest,
                        qMemberInformation.content,
                        qMemberInformation.status,
                        qMemberInformation.createTime,
                        qMemberInformation.collectCount))
                .from(qMemberInformation)
                .where(qMemberInformation.columnId.eq(information.getColumnId())
                        .and(qMemberInformation.status.eq(ShelfEnum.ON_SHELF.getCode()))
                        .and(qMemberInformation.id.ne(request.getId()))
                        .and(qMemberInformation.memberId.eq(user.getMemberId()))
                        .and(qMemberInformation.memberRoleId.eq(user.getMemberRoleId())));

        if (information.getThirdlyCategoryId() != null) {
            query.where(qMemberInformation.thirdlyCategoryId.eq(information.getThirdlyCategoryId()));
        }

        //随机排序，取8条数据
        NumberExpression<Double> numberExpression = Expressions.numberTemplate(Double.class, "rand()");
        OrderSpecifier<Double> orderSpecifier = new OrderSpecifier<>(null, numberExpression);

        List<MemberInformationResponse> informationList = query.orderBy(orderSpecifier).limit(8).fetch();

        return Wrapper.success(informationList);
    }

    /**
     * 收藏/取消收藏
     * @param request 请求参数
     * @return 查询结果
     */
    @Override
    @Transactional
    public Wrapper<Void> collect(CollectRequest request, UserLoginCacheDTO user) {
        //根据id获取资讯
        MemberInformation information = memberInformationRepository.findById(request.getInformationId()).orElse(null);
        if (information == null) {
            return Wrapper.fail(ResponseCode.MAN_RECORDS_DON_T_EXIST);
        }

        if (request.getStatus()) {
            if (memberInformationCollectRepository.existsByInformationIdAndMemberIdAndUserId(request.getInformationId(), user.getMemberId(), user.getUserId())) {
                return Wrapper.fail(ResponseCode.PLATFORM_MANAGE_CAN_T_BE_REPEATED);
            }
            MemberInformationCollect collect = new MemberInformationCollect();
            collect.setInformationId(request.getInformationId());
            collect.setMemberId(user.getMemberId());
            collect.setUserId(user.getUserId());
            collect.setSelfMemberId(information.getMemberId());
            collect.setUrl(request.getUrl());
            memberInformationCollectRepository.saveAndFlush(collect);
        } else {
            memberInformationCollectRepository.deleteByInformationIdAndMemberIdAndUserId(request.getInformationId(), user.getMemberId(), user.getUserId());
        }

        //更新资讯收藏数
        information.setCollectCount(request.getStatus() ? 1 : -1);
        memberInformationRepository.saveAndFlush(information);

        return Wrapper.success();
    }

    /**
     * 收藏列表
     * @param request 请求参数
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<ContentInformationResponse>> collectList(PageVO request, UserLoginCacheDTO user) {
        //分页查询当前登录用户收藏资讯信息
        Pageable page = PageRequest.of(request.getCurrent() - 1, request.getPageSize(), Sort.by("createTime").descending());
        Page<MemberInformationCollect> result = memberInformationCollectRepository.findAllByMemberIdAndUserId(user.getMemberId(), user.getUserId(), page);
        List<MemberInformationCollect> contentInformationResponseList = result.getContent();

        if (CollectionUtil.isNotEmpty(contentInformationResponseList)) {
            List<Long> informationIdList = contentInformationResponseList.stream().map(MemberInformationCollect::getInformationId).collect(Collectors.toList());
            List<MemberInformation> allByIds = memberInformationRepository.findAllById(informationIdList);
            if (CollectionUtil.isNotEmpty(allByIds)) {
                List<MemberColumn> allColumn = memberColumnRepository.findAll();
                List<MemberLabel> allLabel = memberLabelRepository.findAll();

                List<ContentInformationResponse> responses = allByIds.stream().map(a -> {
                    ContentInformationResponse response = new ContentInformationResponse();
                    BeanUtils.copyProperties(a, response);

                    MemberColumn contentColumn = allColumn.stream().filter(b -> b.getId().equals(a.getColumnId())).findFirst().orElse(null);
                    response.setColumnName(contentColumn == null ? "" : contentColumn.getName());

                    if (CollectionUtil.isNotEmpty(a.getLabelIds())) {
                        List<Map<String, Object>> contentLabelList = allLabel.stream()
                                .filter(b -> a.getLabelIds().stream().anyMatch(c -> c.equals(b.getId())))
                                .map(d -> {
                                    Map<String, Object> contentLabel = new HashMap<>();
                                    contentLabel.put("id", d.getId());
                                    contentLabel.put("name", d.getName());
                                    return contentLabel;
                                }).collect(Collectors.toList());
                        response.setContentLabelList(contentLabelList);
                    }

                    Long collectTime = contentInformationResponseList.stream().filter(b -> b.getInformationId().equals(a.getId())).mapToLong(MemberInformationCollect::getCreateTime).findFirst().orElse(0L);
                    response.setCollectTime(collectTime);

                    String url = contentInformationResponseList.stream().filter(b -> b.getInformationId().equals(a.getId())).map(MemberInformationCollect::getUrl).findFirst().orElse("");
                    response.setUrl(url);
                    return response;
                }).sorted(Comparator.comparing(ContentInformationResponse::getCollectTime).reversed()).collect(Collectors.toList());

                return Wrapper.success(new PageData<>(result.getTotalElements(), responses));
            }
        }

        return Wrapper.success(new PageData<>(0L, new ArrayList<>()));
    }

    /**
     * 列表（装修）
     * @param request 请求参数
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<MemberInformationListAdornResponse>> listAdorn(ContentInformationListAdornRequest request, UserLoginCacheDTO user) {
        //查询表实体 - 资讯
        QMemberInformation qMemberInformation = QMemberInformation.memberInformation;

        //查询条件构造 - 必要条件
        BooleanBuilder predicates = new BooleanBuilder();
        predicates.and(qMemberInformation.status.eq(ShelfEnum.ON_SHELF.getCode()));
        predicates.and(qMemberInformation.memberId.eq(user.getMemberId()));
        predicates.and(qMemberInformation.memberRoleId.eq(user.getMemberRoleId()));

        //搜索条件
        if (StringUtils.isNotBlank(request.getTitle())) {
            predicates.and(qMemberInformation.title.like("%" + request.getTitle() + "%"));
        }
        if (request.getIdInList() != null) {
            predicates.and(qMemberInformation.id.in(request.getIdInList()));
        }
        if (request.getIdNotInList() != null) {
            predicates.and(qMemberInformation.id.notIn(request.getIdNotInList()));
        }

        //查询
        JPAQuery<MemberInformationListAdornResponse> query = jpaQueryFactory
                .select(Projections.bean(MemberInformationListAdornResponse.class,
                        qMemberInformation.id,
                        qMemberInformation.columnId,
                        qMemberInformation.title,
                        qMemberInformation.imageUrl,
                        qMemberInformation.createTime))
                .from(qMemberInformation).where(predicates);

        //总记录数
        long totalCount = query.fetchCount();

        //列表数据
        List<MemberInformationListAdornResponse> list = query.orderBy(qMemberInformation.id.desc()).offset(request.getCurrentOffset()).limit(request.getPageSize()).fetch();

        //封装栏目名称
        List<MemberColumn> allColumn = memberColumnRepository.findAll();
        list = list.stream().peek(a -> {
            MemberColumn memberColumn = allColumn.stream().filter(b ->
                    b.getId().equals(a.getColumnId())
            ).findFirst().orElse(new MemberColumn());
            a.setColumnName(memberColumn.getName());
        }).collect(Collectors.toList());

        return Wrapper.success(new PageData<>(totalCount, list));
    }
}
